using System;
using System.Collections.Generic;
using System.Text;

using MVPlan.Engine;
using MVPlan.Engine.Gases;

namespace MVPlan.Engine.Segment
{
    /// <summary>
    /// Class of segment for describing ascent/descent dive segments. Specialisation of AbstractSegment.
    /// </summary>
    [Serializable]
	public class SegmentAscDec : SegmentAbstract
    {
        #region Members

        private double rate; // Ascent (+ve)/ Descent (-ve) rate in msw/sec

        #endregion

        #region Properties
        
        /// <summary>
        /// Gets ascent rate for segment.
        /// </summary>
        virtual public double Rate
        {
            get
            {
                return rate;
            }

            set
            {
                rate = value;
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// Override GasUsed() to determine the gas used in this segment.
        /// </summary>
        public override double GasUsed()
        {
            if (setpoint > 0)
                return (0);

            double p; // pressure
            double d; // depth
            double startDepth;

            startDepth = depth - rate * time;
            
            // Calculate average depth
            d = startDepth + (depth - startDepth) / 2.0;
            p = (d + Prefs.Current.PAmb) / Prefs.Current.PConversion; // Convert to pressure (atm);     
            
            return (p * time * Prefs.Current.RMVDive);
        }

        #endregion

        #region Constructors

        public SegmentAscDec()
        {

        }

        
        /// <summary> 
        /// Constructor for objects of class SegmentAscDec.
        /// </summary>
		/// <param name="gas">Gas object for this segment</param>
		/// <param name="startDepth">Starting depth of segment in m (ft)</param>
		/// <param name="endDepth">Ending depth of segment in m (ft)</param>
		/// <param name="rate">Rate of change of depth in m/min (ft/min)</param>
		/// <param name="setpoint">Setpoint for segment, or 0 for open circuit</param>
		public SegmentAscDec(double startDepth, double endDepth, double rate, Gas gas, double setpoint):base()
		{
			base.depth = endDepth;
			base.gas = gas;
			base.setpoint = setpoint;

			// Init this class fields
			this.rate = rate;
			base.time = (endDepth - startDepth) / rate;
			if (startDepth < endDepth)
				base.type = SegmentType.DESCENT;
			else
				base.type = SegmentType.ASCENT;
        }

        #endregion
    }
}

